using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Ltf.Diffs
{
	

	public class Diff3NoBaseDocument : DiffDocument, IDiff3Document
	{

		public Diff3NoBaseDocument(string fileName)
		: base(fileName) {	}


		public void SetDiff3(Diff3Results results, DiffSide side)
		{
			switch (side)
			{
				case DiffSide.Left:
					SetDiff3FullViewLeft(results);
					break;
				case DiffSide.Right:
					SetDiff3FullViewRight(results);
					break;
				case DiffSide.Combined:
					throw new NotImplementedException("Combined view not implemented for Diff3Results");
				default:
					break;
			}
		}

		public void SetDiff3MergeView(Diff3Results results, DiffSide side, MergeChangesToDisplay mergeChangesToDisplay)
		{
			this.mergeChangesToDisplay = mergeChangesToDisplay;

			switch (side)
			{
				case DiffSide.Left:
					SetDiff3MergeViewLeft(results);
					break;
				case DiffSide.Right:
					SetDiff3MergeViewRight(results);
					break;
				case DiffSide.Combined:
					throw new NotImplementedException("Combined view not implemented for Diff3Results");
				default:
					break;
			}
		}

		public void SetDiff3FullViewLeft(Diff3Results results)
		{
			// showing base and server changes - added lines to keep in sync with local
			// main file based on server file.
			int blankLineOffset = 0;
			foreach (Diff3Results.Diff3Hunk hunk in results.Hunks)
			{
				switch (hunk.HunkType)
				{
					case Diff3Results.Diff3HunkType.AllDiff:
						if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
						{
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
							{
								Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
								//Line builtline = new Line(LineState.Inserted, hunk.ServerLines[line - hunk.ServerRange.From]);
								//Lines.Insert(hunk.ServerRange.From + blankLineOffset, builtline);
								//blankLineOffset++;
							}
							if (hunk.LocalRange.Interval > hunk.ServerRange.Interval)
							{
								for (int i = 0; i < (hunk.LocalRange.Interval - hunk.ServerRange.Interval); i++)
								{
									Line builtline = new Line(LineState.Inserted, string.Empty);
									Lines.Insert(hunk.ServerRange.To + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
						}
						else if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.Deleted, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.ServerRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
							//if (hunk.LocalRange.Interval > hunk.BaseRange.Interval)
							//{
							for (int i = 0; i < (hunk.LocalRange.Interval); i++)
							{
								Line builtline = new Line(LineState.Deleted, string.Empty);
								Lines.Insert(hunk.ServerRange.To + blankLineOffset, builtline);
								blankLineOffset++;
								//}
							}
						}
						else
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
							if (hunk.LocalRange.Interval > hunk.ServerRange.Interval)
							{
								for (int i = 0; i < (hunk.LocalRange.Interval - hunk.ServerRange.Interval); i++)
								{
									Line builtline = new Line(LineState.ChangedFrom, string.Empty);
									Lines.Insert(hunk.ServerRange.To + blankLineOffset - 1, builtline);
									blankLineOffset++;
								}
							}
						}
						break;

					case Diff3Results.Diff3HunkType.LocalDiff:
						if (hunk.ServerRange.RangeType != Diff3Results.RangeType.Add)
						{
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.SyncOnly);
						}
						if (hunk.LocalRange.Interval > 0 && hunk.LocalRange.RangeType != Diff3Results.RangeType.Add) //hunk.ServerRange.Interval)
						{
							for (int i = 0; i < (hunk.LocalRange.Interval); i++)
							{
								Line builtline = new Line(LineState.SyncOnly, string.Empty);
								Lines.Insert(hunk.ServerRange.To + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}

						break;

					case Diff3Results.Diff3HunkType.BaseDiff:
						if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.Deleted, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.ServerRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}
						else if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
						{
							//for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							//{
							//  Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
							//  Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
							//  blankLineOffset++;
							//}
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
						}
						else
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
						}
						break;
					case Diff3Results.Diff3HunkType.ServerDiff:
						if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.Deleted, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.ServerRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}
						else if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
							{
								Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
							}
						}

						else
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
						}
						break;
					default:
						break;
				}
			}

		}

		public void SetDiff3FullViewRight(Diff3Results results)
		{
			// showing base and Local changes - added lines to keep in sync with local
			// main file based on Local file.
			int blankLineOffset = 0;
			foreach (Diff3Results.Diff3Hunk hunk in results.Hunks)
			{
				switch (hunk.HunkType)
				{
					case Diff3Results.Diff3HunkType.AllDiff:
						if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
						{
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							{
								Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
								//Line builtline = new Line(LineState.ConflictAdd, hunk.LocalLines[line - hunk.LocalRange.From]);
								//Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
								//blankLineOffset++;
							}
							if (hunk.ServerRange.Interval > hunk.LocalRange.Interval)
							{
								for (int i = 0; i < (hunk.LocalRange.Interval - hunk.ServerRange.Interval); i++)
								{
									Line builtline = new Line(LineState.Inserted, string.Empty);
									Lines.Insert(hunk.LocalRange.To + blankLineOffset - 1, builtline);
									blankLineOffset++;
								}
							}
						}
						else if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							{
								Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
							}
							if (hunk.ServerRange.Interval > hunk.LocalRange.Interval)
							{
								for (int i = 0; i < (hunk.ServerRange.Interval - hunk.LocalRange.Interval); i++)
								{
									Line builtline = new Line(LineState.ChangedTo, string.Empty);
									Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
						}
						else if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.Deleted, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
							if (hunk.BaseRange.Interval > hunk.LocalRange.Interval)
							{
								for (int i = 0; i < (hunk.BaseRange.Interval); i++)
								{
									Line builtline = new Line(LineState.Deleted, string.Empty);
									Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
						}
						else
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
							if (hunk.ServerRange.Interval > hunk.LocalRange.Interval)
							{
								for (int i = 0; i < (hunk.ServerRange.Interval - hunk.LocalRange.Interval); i++)
								{
									Line builtline = new Line(LineState.SyncOnly, string.Empty);
									Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
						}
						break;
					case Diff3Results.Diff3HunkType.ServerDiff:
						if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
							{
								Line builtline = new Line(LineState.SyncOnly, string.Empty); //hunk.ServerLines[line - hunk.ServerRange.From]);
//								Line builtline = new Line(LineState.MergeableAdd, hunk.ServerLines[line - hunk.ServerRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}
						else if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
						{
							//for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							//  Lines[line + blankLineOffset - 1].SetLineProperties(LineState.MergeableDelete);
						}
						else
						{
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.SyncOnly);


							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
							{
								Line builtline = new Line(LineState.SyncOnly, string.Empty); //, hunk.ServerLines[line - hunk.ServerRange.From]);
//								Line builtline = new Line(LineState.ChangedFrom, hunk.ServerLines[line - hunk.ServerRange.From]);
								Lines.Insert(hunk.LocalRange.To + blankLineOffset , builtline);
								blankLineOffset++;
							}
							//for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							//  Lines[line + blankLineOffset - 1].SetLineProperties(LineState.MergeableChange);
						}
						break;

					case Diff3Results.Diff3HunkType.BaseDiff:
						if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.Deleted, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}
						else if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
						{
							//for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							//{
							//  Line builtline = new Line(LineState.ChangedFrom, hunk.ServerLines[line - hunk.BaseRange.From]);
							//  Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
							//  blankLineOffset++;
							//}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
						}
						else
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
						}
						break;
					case Diff3Results.Diff3HunkType.LocalDiff:
						if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.Deleted, hunk.ServerLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}
						else if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							{
								Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
							}
						}

						else
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.ChangedFrom, hunk.ServerLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
						}
						break;
					default:
						break;
				}
			}

		}

		public void SetDiff3MergeViewLeft(Diff3Results results)
		{
			// showing base and server changes - added lines to keep in sync with local
			// main file based on server file.
			int blankLineOffset = 0;
			foreach (Diff3Results.Diff3Hunk hunk in results.Hunks)
			{
				switch (hunk.HunkType)
				{
					case Diff3Results.Diff3HunkType.AllDiff:
//						if ((mergeChangesToDisplay & MergeChangesToDisplay.Conflicts) != 0)
						{
							if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
							{
								for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								{
									Lines[line + blankLineOffset - 1].SetLineState(LineState.ConflictAdd);
									//Line builtline = new Line(LineState.Inserted, hunk.ServerLines[line - hunk.ServerRange.From]);
									//Lines.Insert(hunk.ServerRange.From + blankLineOffset, builtline);
									//blankLineOffset++;
								}
								if (hunk.LocalRange.Interval > hunk.ServerRange.Interval)
								{
									for (int i = 0; i < (hunk.LocalRange.Interval - hunk.ServerRange.Interval); i++)
									{
										Line builtline = new Line(LineState.Inserted, string.Empty);
										Lines.Insert(hunk.ServerRange.To + blankLineOffset, builtline);
										blankLineOffset++;
									}
								}
							}
							else if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
							{
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.ConflictDelete, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.ServerRange.From + blankLineOffset, builtline);
									blankLineOffset++;
								}
								//if (hunk.LocalRange.Interval > hunk.BaseRange.Interval)
								//{
								for (int i = 0; i < (hunk.LocalRange.Interval); i++)
								{
									Line builtline = new Line(LineState.ConflictDelete, string.Empty);
									Lines.Insert(hunk.ServerRange.To + blankLineOffset, builtline);
									blankLineOffset++;
									//}
								}
							}
							else
							{
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
									blankLineOffset++;
								}
								for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.ConflictChange);
								if (hunk.LocalRange.Interval > hunk.ServerRange.Interval)
								{
									for (int i = 0; i < (hunk.LocalRange.Interval - hunk.ServerRange.Interval); i++)
									{
										Line builtline = new Line(LineState.SyncOnly, string.Empty);
										Lines.Insert(hunk.ServerRange.To + blankLineOffset , builtline);
										blankLineOffset++;
									}
								}
							}
						}
						break;

					case Diff3Results.Diff3HunkType.LocalDiff:
						if (hunk.ServerRange.RangeType != Diff3Results.RangeType.Add)
						{
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.SyncOnly);
						}
						if (hunk.LocalRange.Interval > 0 && hunk.LocalRange.RangeType != Diff3Results.RangeType.Add) //hunk.ServerRange.Interval)
						{
							for (int i = 0; i < (hunk.LocalRange.Interval); i++)
							{
								Line builtline = new Line(LineState.SyncOnly, string.Empty);
								Lines.Insert(hunk.ServerRange.To + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}

						break;

					case Diff3Results.Diff3HunkType.BaseDiff:
//						if ((mergeChangesToDisplay & MergeChangesToDisplay.Same) != 0)
						{
							if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
							{
								//lines were removed from base, so show them as deletions
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.Deleted, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.ServerRange.From + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
							else if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
							{
								//for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								//{
								//  Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
								//  Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
								//  blankLineOffset++;
								//}
								for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
							}
							else
							{
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
									blankLineOffset++;
								}
								for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
							}
						}
						break;
					case Diff3Results.Diff3HunkType.ServerDiff:
	//					if ((mergeChangesToDisplay & MergeChangesToDisplay.Mergeable) != 0)
						{
							if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
							{
								//lines were removed from base, so show them as deletions
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.Deleted, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.ServerRange.From + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
							else if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
							{
								//lines were removed from base, so show them as deletions
								for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								{
									Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
								}
							}

							else
							{
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
									blankLineOffset++;
								}
								for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
							}
						}
						break;
					default:
						break;
				}
			}

		}

		public void SetDiff3MergeViewRight(Diff3Results results)
		{
			// showing base and Local changes - added lines to keep in sync with local
			// main file based on Local file.
			int blankLineOffset = 0;
			foreach (Diff3Results.Diff3Hunk hunk in results.Hunks)
			{
				switch (hunk.HunkType)
				{
					case Diff3Results.Diff3HunkType.AllDiff:
			//			if ((mergeChangesToDisplay & MergeChangesToDisplay.Conflicts) != 0)
						{
							if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
							{
								for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
								{
									Lines[line + blankLineOffset - 1].SetLineState(LineState.ConflictAdd);
									//Line builtline = new Line(LineState.ConflictAdd, hunk.LocalLines[line - hunk.LocalRange.From]);
									//Lines.Insert(hunk.ServerRange.From + blankLineOffset - 1, builtline);
									//blankLineOffset++;
								}
								if (hunk.ServerRange.Interval > hunk.LocalRange.Interval)
								{
									for (int i = 0; i < (hunk.LocalRange.Interval - hunk.ServerRange.Interval); i++)
									{
										Line builtline = new Line(LineState.ConflictAdd, string.Empty);
										Lines.Insert(hunk.LocalRange.To + blankLineOffset - 1, builtline);
										blankLineOffset++;
									}
								}
							}
							else if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
							{
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
									blankLineOffset++;
								}
								for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
								{
									Lines[line + blankLineOffset - 1].SetLineState(LineState.ConflictChange);
								}
								if (hunk.ServerRange.Interval > hunk.LocalRange.Interval)
								{
									for (int i = 0; i < (hunk.ServerRange.Interval - hunk.LocalRange.Interval); i++)
									{
										Line builtline = new Line(LineState.ConflictChange, string.Empty);
										Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
										blankLineOffset++;
									}
								}
							}
							else if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
							{
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.ConflictDelete, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
									blankLineOffset++;
								}
								if (hunk.BaseRange.Interval > hunk.LocalRange.Interval)
								{
									for (int i = 0; i < (hunk.BaseRange.Interval); i++)
									{
										Line builtline = new Line(LineState.ConflictDelete, string.Empty);
										Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
										blankLineOffset++;
									}
								}
							}
							else
							{
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
									blankLineOffset++;
								}
								for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.ConflictChange);
								if (hunk.ServerRange.Interval > hunk.LocalRange.Interval)
								{
									for (int i = 0; i < (hunk.ServerRange.Interval - hunk.LocalRange.Interval); i++)
									{
										Line builtline = new Line(LineState.SyncOnly, string.Empty);
										Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
										blankLineOffset++;
									}
								}
							}
						}
						break;
					case Diff3Results.Diff3HunkType.ServerDiff:
	//					if ((mergeChangesToDisplay & MergeChangesToDisplay.Mergeable) != 0)
						{
							if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
							{
								//lines were removed from base, so show them as deletions
								for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								{
									Line builtline = new Line(LineState.MergeableAdd, hunk.ServerLines[line - hunk.ServerRange.From]);
									Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
							else if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
							{
								for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.MergeableDelete);
							}
							else
							{
								for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedFrom);
								for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
								{
									Line builtline = new Line(LineState.MergeableChange, hunk.ServerLines[line - hunk.ServerRange.From]);
									Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
						}
						break;

					case Diff3Results.Diff3HunkType.BaseDiff:
	//					if ((mergeChangesToDisplay & MergeChangesToDisplay.Same) != 0)
						{
							if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
							{
								//lines were removed from base, so show them as deletions
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.SameDelete, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
							else if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
							{
								//for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								//{
								//  Line builtline = new Line(LineState.ChangedFrom, hunk.ServerLines[line - hunk.BaseRange.From]);
								//  Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								//  blankLineOffset++;
								//}
								for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.SameAdd);
							}
							else
							{
								for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
								{
									Line builtline = new Line(LineState.ChangedFrom, hunk.BaseLines[line - hunk.BaseRange.From]);
									Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
									blankLineOffset++;
								}
								for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
									Lines[line + blankLineOffset - 1].SetLineState(LineState.SameChange);
							}

						}
						break;
					case Diff3Results.Diff3HunkType.LocalDiff:
						if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.Deleted, hunk.ServerLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}
						else if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
						{
							//lines were removed from base, so show them as deletions
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							{
								Lines[line + blankLineOffset - 1].SetLineState(LineState.Inserted);
							}
						}

						else
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.ChangedFrom, hunk.ServerLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.ChangedTo);
						}
						break;
					default:
						break;
				}
			}

		}

		public void SetDiff3Output(Diff3Results results)
		{
			string OutputTextRangeDeleted = "<< Range Deleted >>";
			string OutputTextNoContext = "<< No matching context >>";
			// showing base and Local changes - added lines to keep in sync with local
			// main file based on Local file.
			int blankLineOffset = 0;
			foreach (Diff3Results.Diff3Hunk hunk in results.Hunks)
			{
				switch (hunk.HunkType)
				{
					case Diff3Results.Diff3HunkType.AllDiff:

						if (hunk.BaseRange.RangeType == Diff3Results.RangeType.Add)
						{
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
							{
								Line builtline = new Line(LineState.MergeTheirs, hunk.ServerLines[line - hunk.ServerRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							{
								Lines[line + blankLineOffset - 1].SetLineState(LineState.MergeYours);
							}
						}
						else if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
						{
							{
								Line builtline = new Line(LineState.MergeNoLinesTheirs, OutputTextRangeDeleted);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							{
								Lines[line + blankLineOffset - 1].SetLineState(LineState.MergeYours);
							}
							if (hunk.ServerRange.Interval > hunk.LocalRange.Interval)
							{
								for (int i = 0; i < (hunk.ServerRange.Interval - hunk.LocalRange.Interval); i++)
								{
									Line builtline = new Line(LineState.MergeYours, string.Empty);
									Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
									blankLineOffset++;
								}
							}
						}
						else if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
						{
							for (int line = hunk.BaseRange.From; line <= hunk.BaseRange.To; line++)
							{
								Line builtline = new Line(LineState.MergeTheirs, hunk.BaseLines[line - hunk.BaseRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
						  {
								Line builtline = new Line(LineState.MergeNoLinesYours, OutputTextNoContext);
								Lines.Insert(hunk.LocalRange.To + blankLineOffset, builtline);
								blankLineOffset++;
						  }
						}
						else
						{
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
							{
								Line builtline = new Line(LineState.MergeTheirs, hunk.ServerLines[line - hunk.ServerRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset - 1, builtline);
								blankLineOffset++;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
								Lines[line + blankLineOffset - 1].SetLineState(LineState.MergeYours);
							//if (hunk.ServerRange.Interval > hunk.LocalRange.Interval)
							//{
							//  for (int i = 0; i < (hunk.ServerRange.Interval - hunk.LocalRange.Interval); i++)
							//  {
							//    Line builtline = new Line(LineState.MergeYours, string.Empty);
							//    Lines.Insert(hunk.LocalRange.To + blankLineOffset - 1, builtline);
							//    blankLineOffset++;
							//  }
							//}
						}
						break;
					case Diff3Results.Diff3HunkType.ServerDiff:
						if (hunk.LocalRange.RangeType == Diff3Results.RangeType.Add)
						{
							// mergable lines added
							for (int line = hunk.ServerRange.From; line <= hunk.ServerRange.To; line++)
							{
								Line builtline = new Line(LineState.MergedOkay, hunk.ServerLines[line - hunk.ServerRange.From]);
								Lines.Insert(hunk.LocalRange.From + blankLineOffset, builtline);
								blankLineOffset++;
							}
						}
						else if (hunk.ServerRange.RangeType == Diff3Results.RangeType.Add)
						{
							//mergable lines removed
							Line before=null;
							Line after=null;
							List<string> removedLines=new List<string>();
							int oldBlankLineOffset = blankLineOffset;
							if (hunk.LocalRange.From > 0)
							{
								before = Lines[hunk.LocalRange.From + blankLineOffset - 2];
								before.StateBelow=LineState.MergedOkay;
							}
							for (int line = hunk.LocalRange.From; line <= hunk.LocalRange.To; line++)
							{
								removedLines.Add(Lines[hunk.LocalRange.From + oldBlankLineOffset-1].Text);
								Lines.RemoveAt(hunk.LocalRange.From + oldBlankLineOffset - 1);
								blankLineOffset--;
							}
							if (hunk.LocalRange.To < Lines.Count)
							{
								Lines[hunk.LocalRange.To + blankLineOffset].StateAbove=LineState.MergedOkay;
								after = Lines[hunk.LocalRange.To + blankLineOffset];
							}
							if (before!=null)
								before.DeletedLines.Below=removedLines;
							if (after!=null)
								after.DeletedLines.Above=removedLines;
						}
						else
						{
							//mergeable lines changed
							List<string> removedLines = new List<string>();
							int oldBlankLineOffset = blankLineOffset;
							for (int line = 0; line < hunk.LocalRange.Interval; line++)
							{
								removedLines.Add(Lines[hunk.LocalRange.From + oldBlankLineOffset-1].Text);
								Lines.RemoveAt(hunk.LocalRange.From + oldBlankLineOffset-1);
								blankLineOffset--;
							}
							for (int line = 0; line < hunk.ServerRange.Interval; line++)
							{
								Line builtline = new Line(LineState.MergedOkay, hunk.ServerLines[line]);
								builtline.DeletedLines.Here = removedLines;
								Lines.Insert(hunk.LocalRange.From + blankLineOffset -1 + hunk.LocalRange.Interval, builtline);
								blankLineOffset++;
							}

						}

						break;

					case Diff3Results.Diff3HunkType.LocalDiff:
						break;
					default:
						break;
				}
			}

		}


		public override void LoadResults(Diff3Results results)
		{
			throw new Exception("The method or operation is not implemented.");
		}
	}

}